<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!-- saved from url=(0042)http://icalvalid.wikidot.com/wild-examples -->
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Wild Examples - iCalendar Validation</title>
    
    
        
    <script type="text/javascript" async="" src="./Wild Examples - iCalendar Validation_files/quant.js"></script><script type="text/javascript" async="" src="./Wild Examples - iCalendar Validation_files/ga.js"></script><script type="text/javascript" src="./Wild Examples - iCalendar Validation_files/init.combined.js"></script>
    <script type="text/javascript">
        var URL_HOST = 'www.wikidot.com';
        var URL_DOMAIN = 'wikidot.com';
        var USE_SSL =  true ;
        var URL_STATIC = 'http://d3g0gp89917ko0.cloudfront.net/v--5f298b4ffcd1';
        // global request information
        
        var WIKIREQUEST = {};
        WIKIREQUEST.info = {};
        
        WIKIREQUEST.info.domain = "icalvalid.wikidot.com";
        WIKIREQUEST.info.siteId = 93183;
        WIKIREQUEST.info.categoryId = 514135;
        WIKIREQUEST.info.themeId = 2;
        WIKIREQUEST.info.requestPageName = "wild-examples";
        OZONE.request.timestamp = 1355033688;
        OZONE.request.date = new Date();
        WIKIREQUEST.info.lang = 'en';
                WIKIREQUEST.info.pageUnixName = "wild-examples";
        WIKIREQUEST.info.pageId = 3146655;
                        WIKIREQUEST.info.lang = "en";
        OZONE.lang = "en";
    </script>
    
    
            
    
    
    <meta http-equiv="content-language" content="en">
    <script type="text/javascript" src="./Wild Examples - iCalendar Validation_files/WIKIDOT.combined.js"></script>
    
    <style type="text/css">
body {
  background-position: center 24px;
}
</style>
<style type="text/css" id="internal-style">
        
        /* modules */
@import url(http://d3g0gp89917ko0.cloudfront.net/v--5f298b4ffcd1/common--modules/css/wiki/pagestagcloud/PagesTagCloudModule.css);
@import url(http://d3g0gp89917ko0.cloudfront.net/v--5f298b4ffcd1/common--modules/css/monetize/textlinkads/MonetizeTextLinkAdsModule.css);


        
        /* theme */
                    @import url(http://d3g0gp89917ko0.cloudfront.net/v--5f298b4ffcd1/common--theme/base/css/style.css);
                    @import url(http://d3g0gp89917ko0.cloudfront.net/v--5f298b4ffcd1/common--theme/clean/css/style.css);
            </style>
    
    <link rel="shortcut icon" href="http://icalvalid.wikidot.com/local--favicon/favicon.gif">
    <link rel="icon" type="image/gif" href="http://icalvalid.wikidot.com/local--favicon/favicon.gif">
    
            <link rel="alternate" type="application/wiki" title="Edit this page" href="javascript:WIKIDOT.page.listeners.editClick()">
    
        <script type="text/javascript">
        var _gaq = _gaq || [];
        _gaq.push(['_setAccount', 'UA-18234656-1']);
        _gaq.push(['_setDomainName', 'none']);
        _gaq.push(['_setAllowLinker', true]);
        _gaq.push(['_trackPageview']);

        _gaq.push(['old._setAccount', 'UA-68540-5']);
        _gaq.push(['old._setDomainName', 'none']);
        _gaq.push(['old._setAllowLinker', true]);
        _gaq.push(['old._trackPageview']);

            </script>
    
    <script type="text/javascript">
        window.google_analytics_uacct = 'UA-18234656-1';
        window.google_analytics_domain_name = 'none';
    </script>
<script type="text/javascript" src="./Wild Examples - iCalendar Validation_files/NewPageHelperModule.js"></script></head>

  <body id="html-body">
  <a name="page-top"></a>
  <div id="navi-bar">
  <a class="logo" href="http://www.wikidot.com/">
    <span>Wikidot.com</span>
  </a>
  
  
  
  <div class="new-site">
    <form method="get" action="http://www.wikidot.com/new-site">
      <input class="text empty" type="text" name="address" value="site-name">.wikidot.com
    </form>
  </div>
  
    <div class="share">
    <span>Share on</span>
    <a class="twitter" target="_blank" rel="nofollow" href="http://twitter.com/home?status=Wild%20Examples%20-%20iCalendar%20Validation+http%3A%2F%2Ficalvalid.wikidot.com%2Fwild-examples" title="Share on Twitter"><img src="./Wild Examples - iCalendar Validation_files/twitter.png" alt="twitter"></a>  
    <a class="facebook" target="_blank" rel="nofollow" href="http://www.facebook.com/share.php?u=http%3A%2F%2Ficalvalid.wikidot.com%2Fwild-examples&t=Wild%20Examples%20-%20iCalendar%20Validation" title="Share on Facebook"><img src="./Wild Examples - iCalendar Validation_files/facebook.gif" alt="Facebook"></a>  
    <a class="delicious" target="_blank" rel="nofollow" href="http://delicious.com/save" title="Share on Delicious"><img src="./Wild Examples - iCalendar Validation_files/delicious.png" alt="Delicious"></a>
    <a class="digg" target="_blank" rel="nofollow" href="http://digg.com/submit?url=http%3A%2F%2Ficalvalid.wikidot.com%2Fwild-examples&title=Wild%20Examples%20-%20iCalendar%20Validation" title="Post to Digg"><img src="./Wild Examples - iCalendar Validation_files/digg.png" alt="Digg"></a>
    <a class="reddit" href="http://www.reddit.com/submit?url=http%3A%2F%2Ficalvalid.wikidot.com%2Fwild-examples" rel="nofollow" target="_blank" title="Post to Reddit"><img src="./Wild Examples - iCalendar Validation_files/reddit.png" alt="Reddit" border="0"></a>
    <a class="stumbleupon" href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Ficalvalid.wikidot.com%2Fwild-examples" rel="nofollow" target="_blank" title="Post to StumbleUpon"><img src="./Wild Examples - iCalendar Validation_files/stumble.png" alt="Reddit" border="0"></a>
  </div>
    
    
      <div class="action-buttons">
      <a href="javascript:;" onclick="WIKIDOT.page.listeners.editClick(event)" title="Click here to edit contents of this page.">Edit</a>
      <a href="javascript:;" onclick="WIKIDOT.page.listeners.historyClick(event)" title="Check out how this page has evolved in the past.">History</a>
      <a href="javascript:;" onclick="WIKIDOT.page.listeners.editTags(event)" title="Edit tags for this page.">Tags</a>
      <a href="javascript:;" onclick="WIKIDOT.page.listeners.viewSourceClick(event)" title="View wiki source for this page without editing.">Source</a>
    </div>
    
  <a class="random-site" href="http://icalvalid.wikidot.com/random-site.php" title="Go to a random Wikidot site.">Explore »</a>
  </div>
<div id="navi-bar-shadow">&nbsp;</div>


<script type="text/javascript">
  //<![CDATA[
  $j(function(){
    var uri = window.location.href;
    var title = document.title
    
    $j('#navi-bar .share a').each(function(){
      $t = $j(this);
      var u = $t.attr('href');
      u = u.replace(/TITLE/, encodeURIComponent(title)).replace(/URI/, encodeURIComponent(uri));
      $t.attr('href', u);
    });
    
    $j('#navi-bar .share .facebook').click(function(e){
      window.open('http://www.facebook.com/sharer.php?u='+encodeURIComponent(uri)+'&t='+encodeURIComponent(title),'sharer','toolbar=0,status=0,width=626,height=436');
      e.preventDefault();
    });
    $j('#navi-bar .share .delicious').click(function(e){
      window.open('http://delicious.com/save?v=5&amp;noui&amp;jump=close&amp;url='+encodeURIComponent(location.href)+'&amp;title='+encodeURIComponent(document.title), 'delicious','toolbar=no,width=550,height=550');
      e.preventDefault();
    });
  });
  
	$j('#navi-bar .new-site form').submit(function(e){
	  e.preventDefault();
	  var $i = $j('#navi-bar .new-site form input.text');
	  if($i.hasClass('empty')){
	    	var w = new OZONE.dialogs.ErrorDialog();
  			w.content = "You need to enter a valid web address for your new wiki.";
  			w.show();
  			return;
    }
    var siteName = $i.attr('value');
    siteName = siteName.replace(/^\s+/, '').replace(/\s+$/,'');
		var p = {};
		p.action = 'wiki/special/NewWikiWidgetAction';
		p.event = 'newWiki';
		p.siteName = siteName;
		OZONE.ajax.requestModule(null, p, function(r){
		  if(r.status == 'site_exists'){
		    window.location.href = 'http://' + siteName + '.' + URL_DOMAIN;
		    return;
		  }
		  if(!WIKIDOT.utils.handleError(r)) {return;}
  		// seems fine.
  		window.location.href='http://'+URL_HOST+'/new-site/address/'+r.unixName;
		});
	});
	$j('#navi-bar .new-site form input.text').focus(function(){
	  var $t = $j(this);
	  if($t.hasClass('empty')){
	    $t.removeClass('empty');
	    $t.attr('value', '');
	  }
	});
	//]]>
</script>


  <div id="container-wrap-wrap">
    <div id="container-wrap">
        <div id="container">
            <div id="header">
              <h1><a href="http://icalvalid.wikidot.com/"><span>iCalendar Validation</span></a></h1>
                                
                <!-- google_ad_section_start(weight=ignore) -->
                
                <div id="search-top-box">
                    <form id="search-top-box-form" action="http://icalvalid.wikidot.com/dummy">
                        <input id="search-top-box-input" class="text empty" type="text" size="15" name="query" value="Search this site" onfocus="if(YAHOO.util.Dom.hasClass(this, &#39;empty&#39;)){YAHOO.util.Dom.removeClass(this,&#39;empty&#39;); this.value=&#39;&#39;;}"><input class="button" type="submit" name="search" value="Search">
                    </form>
                </div>
                
                                    <div id="top-bar">
                        

<ul><li><a href="http://icalvalid.wikidot.com/contact">contact</a></li></ul>

                    </div>
                                <div id="login-status"><a href="javascript:;" onclick="WIKIDOT.page.listeners.createAccount(event)" class="login-status-create-account">Create account</a> <span>or</span> <a href="javascript:;" onclick="WIKIDOT.page.listeners.loginClick(event)" class="login-status-sign-in">Sign in</a> </div>
                <div id="header-extra-div-1"><span></span></div><div id="header-extra-div-2"><span></span></div><div id="header-extra-div-3"><span></span></div>
            </div>
            
            <div id="content-wrap">
                                    <div id="side-bar">
                                                    

                                                

<ul><li><a href="http://icalvalid.wikidot.com/start">Welcome page</a></li></ul><ul><li><a href="http://icalvalid.wikidot.com/forum:start">Forum</a></li></ul><ul><li><a href="http://icalvalid.wikidot.com/system:members">Site members</a></li></ul><ul><li><a href="http://icalvalid.wikidot.com/system:recent-changes">Recent changes</a></li><li><a href="http://icalvalid.wikidot.com/system:list-all-pages">List all pages</a></li><li><a href="http://icalvalid.wikidot.com/system:page-tags-list">Page Tags</a></li></ul><ul><li><a href="http://icalvalid.wikidot.com/admin:manage">Site Manager</a></li></ul><h2><span>Page tags</span></h2>
	<div class="pages-tag-cloud-box">
									<a class="tag" href="http://icalvalid.wikidot.com/system:page-tags/tag/ical" style="font-size: 200%; color: rgb(8, 8, 64);">ical</a>
							<a class="tag" href="http://icalvalid.wikidot.com/system:page-tags/tag/icalendar" style="font-size: 80%; color: rgb(100, 100, 128);">icalendar</a>
							<a class="tag" href="http://icalvalid.wikidot.com/system:page-tags/tag/icalvalid" style="font-size: 200%; color: rgb(8, 8, 64);">icalvalid</a>
							<a class="tag" href="http://icalvalid.wikidot.com/system:page-tags/tag/tool" style="font-size: 80%; color: rgb(100, 100, 128);">tool</a>
							<a class="tag" href="http://icalvalid.wikidot.com/system:page-tags/tag/validation" style="font-size: 80%; color: rgb(100, 100, 128);">validation</a>
							<a class="tag" href="http://icalvalid.wikidot.com/system:page-tags/tag/xml" style="font-size: 200%; color: rgb(8, 8, 64);">xml</a>
						</div>
	

<h2><span>Add a new page</span></h2>

<div class="new-page-box" style="text-align: center; margin: 1em 0;">
	<form action="http://icalvalid.wikidot.com/dummy.html" method="get" onsubmit="WIKIDOT.modules.NewPageHelperModule.listeners.create(event);">
		<input class="text" name="pageName" type="text" size="15" maxlength="128" style="margin: 1px">
				<input type="submit" class="button" value="new page" style="margin: 1px;">
																
	</form>
</div>

<p style="text-align: center;"><span style="font-size:80%;"><a href="http://icalvalid.wikidot.com/nav:side">edit this panel</a></span></p>

                                                    

                                            </div>
                                
                <!-- google_ad_section_end -->
                
                <div id="main-content">
                    <div id="action-area-top"></div>
                    
                    <!-- google_ad_section_start -->
                                                                    <div id="page-title">
                        Wild Examples                        </div>
                                                                    
                    
                                                    <div class="wd-adunit">

<script type="text/javascript"><!--
var _wikidot_page_width = null;
try {
    _wikidot_page_width = $j('#main-content').width();
} catch(err){}

google_ad_client = "pub-4131765956051719";
if (_wikidot_page_width && _wikidot_page_width > 740) {
    /* Wikidot 728x90 free site top */
    google_ad_slot = "9539913020";
    google_ad_width = 728;
    google_ad_height = 90;
} else {
    /* Wikidot 300x250 free site top */
    google_ad_slot = "3777757253";
    google_ad_width = 300;
    google_ad_height = 250;
}
//-->
</script>

<script type="text/javascript" src="./Wild Examples - iCalendar Validation_files/show_ads.js">
</script><ins style="display:inline-table;border:none;height:90px;margin:0;padding:0;position:relative;visibility:visible;width:728px"><ins id="aswift_0_anchor" style="display:block;border:none;height:90px;margin:0;padding:0;position:relative;visibility:visible;width:728px"><iframe allowtransparency="true" frameborder="0" height="90" hspace="0" marginwidth="0" marginheight="0" onload="var i=this.id,s=window.google_iframe_oncopy,H=s&amp;&amp;s.handlers,h=H&amp;&amp;H[i],w=this.contentWindow,d;try{d=w.document}catch(e){}if(h&amp;&amp;d&amp;&amp;(!d.body||!d.body.firstChild)){if(h.call){setTimeout(h,0)}else if(h.match){w.location.replace(h)}}" scrolling="no" vspace="0" width="728" id="aswift_0" name="aswift_0" style="left:0;position:absolute;top:0;"></iframe></ins></ins>
</div>
        
    
                                            
                        <div id="page-content">
                            
                                                        

<h2 id="toc0"><span><a href="http://icalvalid.cloudapp.net/?uri=http://jonudell.net/examples/sc_calendar_3325.ics">http://icalvalid.cloudapp.net/?uri=http://jonudell.net/examples/sc_calendar_3325.ics</a></span></h2>
<p>The error is: The calendar could not be parsed due to a serious error in the structure of the calendar: expecting "COLON", found ' '</p>
<p>It would be great to notice that this happens in the DESCRIPTION: field, and to point to examples of properly and improperly formed descriptions.</p>
<p>Ideally the tests included in the schema would be materialized as individual URIs in an HTML namespace, as targets for those pointers.</p>
<h2 id="toc1"><span><a href="http://test.westborough.com/missing_eventprops_calendar.ics">http://test.westborough.com/missing_eventprops_calendar.ics</a></span></h2>
<p>The full test has 277 events missing one or both of DTSTART and DTEND, yet it scores 100 in the validator.</p>
<p>BEGIN:VCALENDAR<br>
VERSION:2.0<br>
PRODID:-<em>SchoolCenter/NONSGML Calendar v9.0</em>EN<br>
BEGIN:VTIMEZONE<br>
TZID:CST<br>
BEGIN:STANDARD<br>
TZNAME:CST<br>
TZOFFSETFROM:-0600<br>
TZOFFSETTO:-0600<br>
END:STANDARD<br>
END:VTIMEZONE<br>
BEGIN:VEVENT<br>
UID:<span class="wiki-email" style="visibility: visible;"><a href="mailto:3325.84815@westborough.ma.schoolwebpages.com">3325.84815@westborough.ma.schoolwebpages.com</a></span><br>
URL:<a href="http://westborough.ma.schoolwebpages.com/education/components/calend">http://westborough.ma.schoolwebpages.com/education/components/calend</a><br>
ar/default.php?sectiondetailid=3325&amp;rid=84815&amp;viewType=detail&amp;et=day<br>
DTSTAMP:20091215T010635Z<br>
LAST-MODIFIED:20090831T180330Z<br>
CLASS:PUBLIC<br>
DESCRIPTION:<br>
END:VEVENT<br>
BEGIN:VEVENT<br>
UID:<span class="wiki-email" style="visibility: visible;"><a href="mailto:3325.84828@westborough.ma.schoolwebpages.com">3325.84828@westborough.ma.schoolwebpages.com</a></span><br>
URL:<a href="http://westborough.ma.schoolwebpages.com/education/components/calend">http://westborough.ma.schoolwebpages.com/education/components/calend</a><br>
ar/default.php?sectiondetailid=3325&amp;rid=84828&amp;viewType=detail&amp;et=day<br>
DTSTAMP:20091215T010638Z<br>
LAST-MODIFIED:20090831T181303Z<br>
DTEND:20100512T230000Z<br>
CLASS:PUBLIC<br>
DESCRIPTION:<br>
END:VEVENT<br>
END:VCALENDAR</p>
<p><strong>Doug:</strong> I've started validation in a strict sense against RFC 2445. Here's a snippet:</p>
<p>; the following are optional,<br>
; but MUST NOT occur more than once</p>
<p>class / created / description / dtstart / geo /<br>
last-mod / location / organizer / priority /<br>
dtstamp / seq / status / summary / transp /<br>
uid / url / recurid /</p>
<p>; either 'dtend' or 'duration' may appear in<br>
; a 'eventprop', but 'dtend' and 'duration'<br>
; MUST NOT occur in the same 'eventprop'</p>
<p>dtend / duration /</p>
<p>So, the main problem is I haven't put together a validation test that goes a step further than this to say "Hey, even though it's technically OK to not have a DTSTART/DTEND, nearly all calendaring applications require them." Thoughts?</p>
<p><strong>Jon</strong> Chuckle. You had this page locked as I was about to copy what I wrote over in the FriendFeed room (<a href="http://friendfeed.com/elmcity/96125f0c/need-some-help-with-busted-ical-file-i-m-crafting">http://friendfeed.com/elmcity/96125f0c/need-some-help-with-busted-ical-file-i-m-crafting</a>):</p>
<p>"This is quite interesting. You've omitted DTSTART and/or DTEND from all of those events. It turns out that's still valid per RFC2445, because all properties are optional. This is a good example of a case where the validator will want to pipe and say: "Did you /really/ mean that?"</p>
<p>Michael's example could serve as the test for that, eh?</p>
<h2 id="toc2"><span><a href="http://www.blogto.com/events/ical/">http://www.blogto.com/events/ical/</a></span></h2>
<p>DDay: expecting "COLON", found ' '</p>
<p>iCal4J: Error was: Error at line 18: Illegal property [ART DOLL GALLERY IN CANADA]</p>
<p>PRODID:PRODID:-<em>blogTO</em>NONSGML Toronto Events V1.0//EN<br>
X-WR-CALNAME:blogTO Toronto Events<br>
X-ORIGINAL-URL:<a href="http://www.blogto.com/events/VERSION:2.0">http://www.blogto.com/events/VERSION:2.0</a><br>
CALSCALE:GREGORIAN<br>
METHOD:PUBLISH<br>
BEGIN:VEVENT<br>
DTSTAMP:20090920T000000<br>
LAST-MODIFIED:20090920T000000<br>
CREATED:20090920T000000<br>
DTSTART:20090901T000000<br>
DTEND:20090901T000000<br>
UID:<br>
SUMMARY: Grand Opening of Art Doll Gallery<br>
LOCATION:The Distillery District<br>
URL:<a href="http://www.blogto.com/events/12776">http://www.blogto.com/events/12776</a><br>
DESCRIPTION;ENCODING=QUOTED-PRINTABLE:Doll Collection presents the grand opening of the first ever =<br>
art doll gallery in Canada=2E<br>
CLASS:PRIVATE<br>
CATEGORIES:<br>
STATUS:CONFIRMED<br>
PARTSTAT:ACCEPTED<br>
END:VEVENT</p>
<p>The PRODID is strange, but I guess the empy UID is the dealbreaker?</p>
<p><strong>Doug:</strong> Yes, looks like DDay.iCal is breaking on the empty UID. Technically, the parser shouldn't complain about this, however. I'll file a bug report and fix this ASAP. It fails in iCal4j due to the improper line folding on the DESCRIPTION property. It would fail in DDay.iCal as well if the parser wasn't already failing on the UID.</p>
<p><strong>Doug:</strong> After some more digging, it appears that DDay.iCal wasn't failing on the empty UID at all. It looks to me like both DDay.iCal and iCal4j are failing on the improper line folding. I'd love to give a better error on this, but the parser isn't very error-friendly with line folding problems.</p>
<p>On a side note, I see a lot of ENCODING=QUOTED-PRINTABLE with the iCalendars you found in the wild, and I don't see any supporting documentation in RFC2445. They mention using Quoted-Printable as a <strong>transfer</strong>-level encoding, but not in a strict file-encoding sense, and certainly not per-parameter encoding. That's one of the things I'd like to have in icalvalid, is a test to ensure calendars only use universally-supported encodings.</p>
<p><strong>Doug:</strong> More digging… QUOTED-PRINTABLE is actually declared in the vCalendar standard (i.e. iCalendar 1.0), and is a recommended form in version 1.0. The iCalendar standard (iCalendar 2.0, aka RFC 2445) doesn't really address it. In my mind, that means they're purposefully avoiding backwards-compatibility with this (which I believe is wise, considering how incomplete iCalendar 1.0 was). <strong>So, the question of the day is: Should DDay.iCal and/or iCal4j support backwards-compatibility with QUOTED-PRINTABLE-encoded properties?</strong></p>
<p>For reference, <a href="http://www.imc.org/pdi/pdiproddev.html">here's the VCalendar 1.0 spec</a>.</p>
<p><strong>Doug:</strong> OK, so after reviewing the VCalendar 1.0 spec a bit further, it looks like even though the spec supports AND recommends QUOTED-PRINTABLE encoding on the per-property basis, it still follows proper line folding techniques. This means DDay.iCal and iCal4j are still correctly handling this — i.e. failing at the parser level. Unfortunately, Outlook 2003+ supports QUOTED-PRINTABLE with improper line folding, which means people may have a lot of incompatibilities between applications that don't like the line folding problems.</p>
<p>In any case, I suppose this just goes to show how much an iCalendar validator would have saved the producers of these calendars from compatibility issues.</p>
<h2 id="toc3"><span><a href="http://www.mobilegeographics.com:81/ical/3988.ics">http://www.mobilegeographics.com:81/ical/3988.ics</a></span></h2>
<p>Are X- properties not supposed to be multiline?</p>
<p>Error: Error was: Error at line 6: Illegal property [ USES UNVERIFIED DATA]<br>
Cause: Caused by: Illegal property [ USES UNVERIFIED DATA]<br>
Context for line 6:</p>
<div class="code">
<pre><code>3: WR-CALNAME:Myrtle Beach, South Carolina 2009
4: PRODID:Mobile Geographics Tides 3988 2009
5: X-WR-CALDESC:Tide/current predictions for Myrtle Beach, South Carolina.
6:   Uses unverified data; not for use in navigation. Includes times/values of
7:   high/low tides, max ebb/flood currents, times of sunrise/sunset/slack,
8:   and dates of moon phases.</code>
</pre></div>
<p><strong>Doug:</strong> No, any item contained in a content line can (and should) be "folded" using this technique. This should not be giving an error. Is it giving an error in both ical4j and DDay.iCal?</p>
<p><strong>Jon:</strong> I thought so. But testing with DDay.iCal outside the aggregator, it seems OK. Must have been a different problem. I'll reset Myrtle Beach and have it try again. Thanks Doug!</p>
<p>This source, found by Dave Slusher, is really cool, BTW. Tides: What a cool thing to put onto a community calendar!</p>
<p><strong>Jon:</strong> PS: Turns out to have been network related. That server makes .NET complain about "protocol violation" — explanation here, <a href="http://www.cookcomputing.com/blog/archives/000556.html">http://www.cookcomputing.com/blog/archives/000556.html</a>, I'm trying the various solutions now.</p>
<p><strong>Doug:</strong> Sounds great, let me know if I can do anything else.</p>
<h2 id="toc4"><span>elmcity generated feeds</span></h2>
<p>Example: <a href="http://elmcity.cloudapp.net/services/fallschurchcals/ics">http://elmcity.cloudapp.net/services/fallschurchcals/ics</a></p>
<p>I recently made some changes to the DDay.iCal-based service that generates ICS for the combined feeds of each location processed by the aggregator. We noticed problems described here: <a href="http://friendfeed.com/elmcity/fbcb2591/elmcity-feed-for-falls-church-is-very-useful">http://friendfeed.com/elmcity/fbcb2591/elmcity-feed-for-falls-church-is-very-useful</a>. ical4j and DDay.iCal both parse the feed successfully, but not all calendar programs seem to. Am investigating why, suggestions welcome.</p>
<p><strong>Doug:</strong> A quick review - the May 21, 2009&nbsp;7:30am event titled "Breakfast Connection" exists in the Google calendar, but not in the URL listed above. Also, it looks like the Google calendar has duplicate entries all over the place. Do you know which calendar feed appears to be "accurate" (if any)?</p>
<p><strong>Jon:</strong> Yes, they're out of sync. GCal is showing the last version it could read. The dupes there are a separate problem with the Eventful API. The version I consider accurate is: <a href="http://elmcity.cloudapp.net/services/fallschurchcals/ics">http://elmcity.cloudapp.net/services/fallschurchcals/ics</a>, also rendered as <a href="http://elmcity.cloudapp.net/services/fallschurchcals/html">http://elmcity.cloudapp.net/services/fallschurchcals/html</a>, <a href="http://elmcity.cloudapp.net/services/fallschurchcals/xml">http://elmcity.cloudapp.net/services/fallschurchcals/xml</a>, <a href="http://elmcity.cloudapp.net/services/fallschurchcals/json">http://elmcity.cloudapp.net/services/fallschurchcals/json</a></p>
<p><strong>Jon:</strong> Found the problem:</p>
<p>curl <a href="http://elmcity.cloudapp.net/services/fallschurchcals/ics">http://elmcity.cloudapp.net/services/fallschurchcals/ics</a> | grep UID | wc<br>
222</p>
<p>curl <a href="http://elmcity.cloudapp.net/services/fallschurchcals/ics">http://elmcity.cloudapp.net/services/fallschurchcals/ics</a> | grep UID | uniq | wc<br>
580</p>
<p>I goofed generating UIDs. This highlights an interesting test case, eh?</p>
<h2 id="toc5"><span>Gilsum, NH</span></h2>
<p><a href="http://www.google.com/calendar/ical/gilsumrocks@gmail.com/public/basic.ics">http://www.google.com/calendar/ical/gilsumrocks@gmail.com/public/basic.ics</a></p>
<p>BEGIN:VEVENT<br>
DTSTART;TZID=America/New_York:20090302T181500<br>
DTEND;TZID=America/New_York:20090302T193000<br>
RRULE:FREQ=WEEKLY;BYDAY=MO;UNTIL=20090330T221500Z;WKST=SU<br>
DTSTAMP:20090309T231544Z<br>
UID:<span class="wiki-email" style="visibility: visible;"><a href="mailto:2m12gkiicmd1amm4350ieg7g1s@google.com">2m12gkiicmd1amm4350ieg7g1s@google.com</a></span><br>
CLASS:PUBLIC<br>
<strong>CREATED:00001231T000000Z</strong><br>
DESCRIPTION:Open to all children. Free! Sponsored by the Gilsum Recreation<br>
Commission.<br>
LAST-MODIFIED:20090305T022216Z<br>
LOCATION:Gilsum Elementary School and Community Center<br>
SEQUENCE:1<br>
STATUS:CONFIRMED<br>
SUMMARY:Youth Basketball<br>
TRANSP:OPAQUE<br>
END:VEVENT</p>
<p>OK in iCal4J.</p>
<p>DDay.iCal: ValueError: Year, Month, Day params describe unrepresentable DateTime.</p>
<p><strong>Doug:</strong> The .NET Framework can only represent DateTime values between January 1, 0001 and December 31, 9999. Since this is represented in the year "0000", it is slightly out of the date/time range that the .NET Framework supports.</p>
<p><strong>Jon:</strong> The spec sez:</p>
<p>Property Name: CREATED</p>
<p>Purpose: This property specifies the date and time that the calendar<br>
information was created by the calendar user agent in the calendar<br>
store.</p>
<p>On the one hand it is silly to claim that the information was created in the year zero. OTOH, the spec doesn't seem to preclude it, so in this case DDay.iCal is arguably penalizing the user for a limitation of the .NET Framework.</p>
<p>Ideally a validator would warn the user that the date is kind of weird, and suggest something more reasonable, but not actually fail.</p>
<p>Since DDay.iCal cannot accommodate the value given, could/should it modify the value to the earliest acceptable one, and insert a COMMENT field explaining that it did that?</p>
<p><strong>Doug:</strong> I think simply mentioning that the date range must be from January 1, 0001 to December 31, 9999 when it fails to parse is sufficient to ensure people stay within a reasonable time frame. Realistically the document was not created in year "0000", so semantically this presents a problem anyhow. I don't think the "penalizing" that occurs here is really out of bounds.</p>
<p><strong>Jon:</strong> Yeah, fair enough. If 10 millenia isn't enough for you, well, get a life :-)</p>
<hr>
<h2 id="toc6"><span>Michigan Gourmet Club</span></h2>
<p><a href="https://ross.ecampusgroups.com/ical/ical_club_7423.ics">https://ross.ecampusgroups.com/ical/ical_club_7423.ics</a></p>
<p>BEGIN:VEVENT<br>
DTSTAMP:20090207T142943<br>
LAST-MODIFIED:20090207T142943<br>
CREATED:20090111T120000<br>
CATEGORIES:GOURMET<br>
DTSTART:20090111T220000Z<br>
DTEND:20090112T000000Z<br>
UID:48c1f4a6-1da2-102c-ac69-00e04cf077a2272009_2:29:<span class="wiki-email" style="visibility: visible;"><a href="mailto:43_PM@ecampusgroups.com">43_PM@ecampusgroups.com</a></span><br>
SUMMARY;ENCODING=QUOTED-PRINTABLE:Wild Game Follow-Up<br>
LOCATION:<br>
URL:<a href="https://ross-gourmet.ecampusgroups.com/rsvp.aspx?event_uid=48c1f4a6-1da2-102c-ac69-00e04cf077a2">https://ross-gourmet.ecampusgroups.com/rsvp.aspx?event_uid=48c1f4a6-1da2-102c-ac69-00e04cf077a2</a><br>
DESCRIPTION:Wild Game Follow-Up\n\n—-\nRSVP: <a href="https://ross-gourmet.ecampusgroups.com/rsvp.aspx?event_uid=48c1f4a6-1da2-102c-ac69-00e04cf077a2">https://ross-gourmet.ecampusgroups.com/rsvp.aspx?event_uid=48c1f4a6-1da2-102c-ac69-00e04cf077a2</a><br>
END:VEVENT</p>
<p>BEGIN:VEVENT<br>
DTSTAMP:20090207T142944<br>
LAST-MODIFIED:20090207T142944<br>
CREATED:20090128T120000<br>
CATEGORIES:GOURMET<br>
DTSTART:20090128T230000Z<br>
DTEND:20090129T010000Z<br>
UID:9aff2740-37b8-102c-ac69-00e04cf077a2272009_2:29:<span class="wiki-email" style="visibility: visible;"><a href="mailto:44_PM@ecampusgroups.com">44_PM@ecampusgroups.com</a></span><br>
SUMMARY;ENCODING=QUOTED-PRINTABLE:Happy Hour at the Earle<br>
LOCATION:The Earle, 121 West Washington, , Ann Arbor, MI, 48104<br>
URL:<a href="https://ross-gourmet.ecampusgroups.com/rsvp.aspx?event_uid=9aff2740-37b8-102c-ac69-00e04cf077a2">https://ross-gourmet.ecampusgroups.com/rsvp.aspx?event_uid=9aff2740-37b8-102c-ac69-00e04cf077a2</a><br>
DESCRIPTION:Happy Hour at the Earle\nThe Earle<br>
<strong>121 West Washington</strong><br>
\nAnn Arbor, MI 48104\n—-\nRSVP: <a href="https://ross-gourmet.ecampusgroups.com/rsvp.aspx?event_uid=9aff2740-37b8-102c-ac69-00e04cf077a2">https://ross-gourmet.ecampusgroups.com/rsvp.aspx?event_uid=9aff2740-37b8-102c-ac69-00e04cf077a2</a><br>
END:VEVENT</p>
<p>Both iCal4J and DDay.iCal choke on 121 West Washington. DESCRIPTION needs to be either all one long line, or preferably broken lines with leading whitespace 2nd and following.</p>
<p>Explaining this to Ross, who runs this Drupal site, will not do him any good. So I'm going to try to compensate with pre-processing. And will point this out to the Drupal folks.</p>
<p>Hmm. Maybe there is a workaround for Ross. He has another Drupal iCalendar feed that works:</p>
<p><a href="https://ross.ecampusgroups.com/ical/ical_club_1657.ics">https://ross.ecampusgroups.com/ical/ical_club_1657.ics</a></p>
<p>Given this information, he might be able to figure out what borked the Gourmet feed and write its description differently.</p>
<p><strong>Doug:</strong> I personally don't believe any iCalendar parser will work well with the above item. Logically speaking about parsing issues such as these, there are few options available to automatically detect things like this. I would consider this the fault of whoever generated the feed.</p>
<p><strong>Jon:</strong> I agree. In these (common) cases where text formatting in DESCRIPTION goes wrong, I am tempted to use pre-processing in my aggregator to try to fix it, and if successful, to insert a COMMENT explaining that I did that. Perhaps a validator could do the same. So in this case it would be forced to report an error instead of a warning. But it could show the user what a successful reformatting would look like.</p>
<hr>
<h2 id="toc7"><span>Meetup DC</span></h2>
<p>iCal4J doesn't like this, but DDay.iCal is OK with it.</p>
<p>URL: <a href="http://www.meetup.com/cities/us/dc/washington/events/ical">http://www.meetup.com/cities/us/dc/washington/events/ical</a></p>
<p>Error: Error was: Error at line 11: Illegal property [ \N\NI'VE STARTED THIS BASED ON THE IDEA OF JELLY\, WHICH ALLOWS PEOPLE WHO ]<br>
Cause: Caused by: Illegal property [ \N\NI'VE STARTED THIS BASED ON THE IDEA OF JELLY\, WHICH ALLOWS PEOPLE WHO ]</p>
<p>Context for line 11:<br>
8: BEGIN:VEVENT<br>
9: SUMMARY:Ebenezer Cafe<br>
10: DESCRIPTION:Telecommuters Meetups &gt; The DC Metro Telecommuters Meetup Group<br>
<strong>11: \n\nI've started this based on the idea of Jelly\, which allows people who</strong><br>
12: work from home to have an office-like setting where you can cowork with oth<br>
13: ers\, have a bit of social time\, or just enjoy getting away from your cat<br>
14: for a few hours (sorry to any offende\n\nWashington\, DC 20002 - USA\n\nMo</p>
<hr>
<h2 id="toc8"><span>Localist</span></h2>
<p><a href="http://baltimore.localist.com/calendar/ics">http://baltimore.localist.com/calendar/ics</a></p>
<p>iCal4J has one complaint:</p>
<p>Error: Error was: Error at line 122: Unparseable date: "20090331"<br>
Cause: Caused by: Unparseable date: "20090331"<br>
Context for line 122:<br>
119: nhttp:<em>www.wodnb.com\nhttp:</em>www.formationrecords.com\n\nhttp:<em>www.shorty<br>
120: sbaltimore.com\nhttp:</em>www.myspace.com/shortysbaltimore\nwww.bmcon.org\nwww<br>
121: .myspace.com/bmoremusic<br>
<strong>122: DTSTART:20090331</strong><br>
123: DTSTAMP:20090406T085200<br>
124: LOCATION:Shorty's Martini Bar &amp; Lounge<br>
125: END:VEVENT</p>
<p>DDay.iCal has a different complaint:</p>
<p>Error loading iCalendar: Geo.Parse cannot parse the value '38.8878738\;-77.4407031' because it is not formatted correctly.</p>
<p><strong>GEO:39.281734\;-76.581864</strong></p>
<p><strong>Doug:</strong> The first error that occurs in iCal4J is that DTSTART did not specify VALUE=DATE. The parser was then unable to recognize the date (not datetime) value that followed. As for the second error - the '\' character is illegal according to RFC 2445. I suppose in DDay.iCal the error message could provide what the format should look like, then in the validation tool provide that message to the user?</p>
<p><strong>Jon:</strong></p>
<p>The spec:</p>
<p>Value Type: The default value type is DATE-TIME. The time value MUST<br>
be one of the forms defined for the DATE-TIME value type. The value<br>
type can be set to a DATE value type.</p>
<p>OK. I understand now. DATE-TIME is the default, if supplying only a DATE, must override with VALUE=DATE. Thanks Doug.</p>
<p>"As for the second error - the '\' character is illegal according to RFC 2445. I suppose in DDay.iCal the error message could provide what the format should look like, then in the validation tool provide that message to the user?"</p>
<p>Or at least explain what went wrong. You have told me here that "the '\' character is illegal according to RFC 2445" but although I might guess that from "Geo.Parse cannot parse the value '38.8878738\;-77.4407031' because it is not formatted correctly" I don't really know without investigating.</p>
<p><strong>Doug:</strong> With the missing VALUE=DATE, the parsing engine should be able to allow this. This <strong>should</strong> instead provide a validation error indicating that VALUE=DATE must be present on their date/time property. With the "Geo.Parse" error, yes, I'll add some additional explanation when it fails to make it clearer what's going on.</p>
<p><strong>Jon:</strong> "With the missing VALUE=DATE, the parsing engine should be able to allow this."</p>
<p>For those of us not very adept at interpreting spec-speak, are you deriving "should be able to allow" from this paragraph?</p>
<p>Value Type: The default value type is DATE-TIME. The time value MUST<br>
be one of the forms defined for the DATE-TIME value type. The value<br>
type can be set to a DATE value type.</p>
<p>My understanding of that para:</p>
<p>1. "The default value type is DATE-TIME." All 3 of the forms mentioned in 4.3.5 of the spec include a TIME value.</p>
<p>2. "The time value MUST be one of the forms defined for the DATE-TIME value type." Given that DATE-TIME is defined in 4.3.5, this stipulation doesn't seem to add any new information, but moving on…</p>
<p>3. "The value type can be set to a DATE value type." Using VALUE=DATE as you suggested, correct? Or are you suggesting that DTSTART:20090331 could be understood by the parser to mean:</p>
<p>DTSTART:20090331T000000</p>
<p>or</p>
<p>DTSTART;VALUE=20090331 ?</p>
<p><strong>Doug:</strong> Lol, I wasn't intending to use "spec-speak" when I said "should be able to allow," but I was merely suggesting that it's not difficult to have your parser "roll with the punches" here. As far as the spec goes, DTSTART states:</p>
<p>dtstart = "DTSTART" dtstparam ":" dtstval CRLF<br>
dtstparam = *(</p>
<p>; the following are optional,<br>
; but MUST NOT occur more than once</p>
<p>(";" "VALUE" "=" ("DATE-TIME" / "DATE")) /<br>
(";" tzidparam) /</p>
<p>; the following is optional,<br>
; and MAY occur more than once</p>
<p>*(";" xparam)</p>
<p>)</p>
<p>This suggests that the VALUE=DATE is optional, as per the actual parsing of the iCalendar file. However, in section 4.3 it states:</p>
<p>"The properties in an iCalendar object are strongly typed. The<br>
definition of each property restricts the value to be one of the<br>
value data types, or simply value types, defined in this section. The<br>
value type for a property will either be specified implicitly as the<br>
default value type or will be explicitly specified with the "VALUE"<br>
parameter. If the value type of a property is one of the alternate<br>
valid types, then it MUST be explicitly specified with the "VALUE"<br>
parameter."</p>
<p>Hence, the parser SHOULD be able to handle it (not MUST), but since the value is not the default value type for DTSTART, the spec states it "MUST be explicitly specified with the "VALUE"<br>
parameter."</p>
<p><strong>Jon:</strong><br>
Hmm. I had overlooked:</p>
<p>dtstval = date-time / date</p>
<p>That suggests you can do this:</p>
<p>DTSTART:20090331T000000</p>
<p>Or this:</p>
<p>DTSTART:20090331</p>
<p>Without any warning or error in either case. Not so?</p>
<p><strong>Doug:</strong> No, it should provide at least a warning (but probably an error). As you noted above for DTSTART, "The default value type is DATE-TIME." According to Section 4.3 it states that if you're using a value type <strong>other</strong> than the default value type, "it MUST be explicitly specified with the 'VALUE' parameter." Therefore, this is incorrect:</p>
<p>DTSTART:20090331</p>
<p>You must instead do this:</p>
<p>DTSTART;VALUE=DATE:20090331</p>
<p>However, this is correct (because it is a date-time type):</p>
<p>DTSTART:20090331T000000</p>
<p>That said, a validation engine should be able to roll with the punches here and accept the value anyway with a warning/error that it does not conform to the standard and may cause problems on some systems.</p>
<p><strong>Ben:</strong> iCal4j will parse this, however you need to enable the "relaxed parsing" Compatibility Hint. Current behaviour will convert the specified date value to a date-time instance, however I'm considering changing this to added the missing "VALUE=DATE" parameter and leaving the date intact..</p>
<p><strong>Jon:</strong></p>
<p>This narrative needs to be refactored :-)</p>
<p>But anyway, the curator for Baltimore, who is using this feed, reminded me that the issue is unresolved. When I rechecked, I reminded myself that DDay.iCal is OK with the DTSTART as is, but not the GEO. Until I can contact the author of the software that writes that feed, I'm preprocessing to change all occurrences of "\;" to just ";" — and that appears to work. But…after I strip out the DTSTARTs that iCal4J doesn't like, it's happy with "\;" which I think is wrong. It's OK to escape a semicolon in a TEXT property, but not in a GEO (or other param=value) property, correct?</p>
<hr>
<h2 id="toc9"><span>Projo the Beat</span></h2>
<p><a href="http://www.projothebeat.com/ical/index?cat=&new=n&search=true&sort=0&srad=20&srss=10&st=event&svt=text&swhat=&swhen=&swhere=Providence%2CRI&trim=1">http://www.projothebeat.com/ical/index?cat=&amp;new=n&amp;search=true&amp;sort=0&amp;srad=20&amp;srss=10&amp;st=event&amp;svt=text&amp;swhat=&amp;swhen=&amp;swhere=Providence%2CRI&amp;trim=1</a></p>
<p>iCal4J is OK with it. DDay.iCal complains:</p>
<p>Error loading iCalendar: expecting "END", found 'VERSION'</p>
<p>BEGIN:VCALENDAR<br>
BEGIN:VTIMEZONE<br>
TZID:US/Eastern<br>
X-LIC-LOCATION:US/Eastern<br>
BEGIN:STANDARD<br>
TZOFFSETFROM:-0400<br>
TZOFFSETTO:-0500<br>
TZNAME:EST<br>
DTSTART:19701025T020000<br>
RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU<br>
END:STANDARD<br>
BEGIN:DAYLIGHT<br>
TZOFFSETFROM:-0500<br>
TZOFFSETTO:-0400<br>
TZNAME:EDT<br>
DTSTART:19700405T020000<br>
RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=1SU<br>
END:DAYLIGHT<br>
END:VTIMEZONE<br>
<strong>VERSION:2.0</strong><br>
CALSCALE:GREGORIAN<br>
METHOD:PUBLISH<br>
PRODID:Zvents Ical<br>
BEGIN:X-CALCONNECT-LOCATION<br>
X-CALCONNECT-NAME:Providence Performing Arts Center<br>
X-CALCONNECT-ADR-REGION:RI<br>
X-CALCONNECT-NAME-CITY:Providence<br>
X-CALCONNECT-NAME-STREET:220 Weybosset St.<br>
X-CALCONNECT-LOCATION-ID:<span class="wiki-email" style="visibility: visible;"><a href="mailto:17655@zvents.com">17655@zvents.com</a></span><br>
X-CALCONNECT-ADR-POSTAL-CODE:02903<br>
X-CALCONNECT-ADR-COUNTRY:United States<br>
END:X-CALCONNECT-LOCATION<br>
BEGIN:VEVENT<br>
SEQUENCE:0<br>
URL;VALUE=URI:<a href="http://www.ppacri.org/schedules/index.cfm">http://www.ppacri.org/schedules/index.cfm</a><br>
CLASS:PUBLIC<br>
PRIORITY:5<br>
UID:84221069:zvents.com<br>
DESCRIPTION:<a href="http://www.zvents.com/providence-ri/events/show/84221069-david">http://www.zvents.com/providence-ri/events/show/84221069-david</a>-<br>
sedaris<br>
SUMMARY:David Sedaris<br>
DTSTART;TZID=US/Eastern:20090406T200000<br>
TRANSP:OPAQUE<br>
DTSTAMP:20090406T132803<br>
LOCATION;X-CALCONNECT-LOCATION-ID=<span class="wiki-email" style="visibility: visible;"><a href="mailto:17655@zvents.com">17655@zvents.com</a></span>:Providence Performing Ar<br>
ts Center 220 Weybosset St. Providence RI United States<br>
END:VEVENT</p>
<p><strong>Doug:</strong> Once again, in RFC 2445, calendar properties must be specified before calendar components. This particular feed is "mix and matching" calendar components and properties. It would be nice if a validator noticed this and pointed that out, however.</p>
<p><strong>Jon:</strong> Exactly. And for now, this document will serve as a proxy for the validator. In a day or so, if somebody is searching for:</p>
<p>Error loading iCalendar: expecting "END", found 'VERSION'</p>
<p>they'll land here, and read your explanation. It's an important first step!</p>
<hr>
<h2 id="toc10"><span>What Grows on in Rhode Island</span></h2>
<p>iCal4J complains, DDay.iCal is OK with it.</p>
<p><a href="http://www.trumba.com/calendars/what-grows-on-in-Rhode-Island.ics">http://www.trumba.com/calendars/what-grows-on-in-Rhode-Island.ics</a></p>
<p>Error: Error was: Error at line 43: Invalid parameter name: NAME<br>
Cause: Caused by: Invalid parameter name: NAME<br>
Context for line 43:<br>
40: CATEGORIES:Service of Providential Gardener ~ <a href="http://www.whatgrowsonri.c/">http://www.whatgrowsonri.c</a><br>
41: om,Art &amp;amp\; Photography ~ Exhibits\, Workshops<br>
42: DTSTAMP:20090215T181200Z<br>
43: X-TRUMBA-CUSTOMFIELD;NAME="Keywords";ID=8318;TYPE=SingleLine:Art Show<br>
44: X-TRUMBA-CUSTOMFIELD;NAME="Additional Info";ID=8089;TYPE=MultiLine:Art O<br>
45: pening will be March 1\, 2009 from 1-3pm<br>
46: X-TRUMBA-CUSTOMFIELD;NAME="Audubon Location";ID=11181;TYPE=Enumeration:A</p>
<p><strong>Jon:</strong></p>
<p>xparam =x-name "=" param-value *("," param-value)</p>
<p>x-name = "X-" [vendorid "-"] 1*(ALPHA / DIGIT / "-")</p>
<p>So it should maybe rather be?</p>
<p>X-TRUMBA-CUSTOMFIELD;X-NAME="Keywords";X-ID=8318;X-TYPE=SingleLine:Art Show</p>
<p>or</p>
<p>or X-TRUMBA-NAME, X-TRUMBA-TYPE</p>
<p>DDay.iCal does not refuse to load this feed. Should it?</p>
<p><strong>Doug:</strong> Technically, yes; realistically, no. The parser can and should handle this just fine - this, once again, should be a validation error warning that "parameters of custom properties must begin with 'X-', or they may not work with all systems.", or something along those lines. Once the icalvalid is further along, this should be one of the tests that it provides to consumers.</p>
<p><strong>Jon:</strong> OK. As per <a href="http://www.feedvalidator.org/docs/">http://www.feedvalidator.org/docs/</a> I guess we'll want to start two new groupings here, one to collect <a class="newpage" href="http://icalvalid.wikidot.com/validationerrors">ValidationErrors</a> and one to collect <a class="newpage" href="http://icalvalid.wikidot.com/validationwarnings">ValidationWarnings</a>. This, I believe you are indicating, would be a Warning but not an Error? That sounds right to me.</p>
<p><strong>Doug:</strong> Yep, I'd put that in the "warning" group.</p>
<p><strong>Ben:</strong> Again, iCal4j will parse it when the "relaxed parsing" Compatibility Hint is enabled. By default iCal4j is as strict as possible, but Compatibility Hints allow for relaxing of commonly broken rules.</p>
<p><strong>Jon:</strong> I found <a href="http://wiki.modularity.net.au/ical4j/index.php?title=Compatibility">http://wiki.modularity.net.au/ical4j/index.php?title=Compatibility</a>. Is there elsewhere a description of what the relaxed mode allows? That'd help us develop a taxonomy of errors vs warnings.</p>
<p><strong>Ben:</strong> Yup, this is all I have documented on the wiki so far. Some more information on what the Compatibility Hints do is available in my recent presentation at CalConnect (slides 9-15): <a href="http://calconnect.org/presentations/iCal4j_Calconnect.pdf">http://calconnect.org/presentations/iCal4j_Calconnect.pdf</a></p>
<h2 id="toc11"><span>Carnation Library</span></h2>
<p><a href="http://eventinfo.kcls.org/evanced/lib/eventsxml.asp?dm=ical&lib=7&alltime=1&nd=60">http://eventinfo.kcls.org/evanced/lib/eventsxml.asp?dm=ical&amp;lib=7&amp;alltime=1&amp;nd=60</a></p>
<p>iCal4J complains: Error was: Error at line 12: Illegal property [TITLE]<br>
DDay.iCal is OK with it.</p>
<p>BEGIN:VCALENDAR<br>
METHOD:PUBLISH<br>
PRODID:e-vanced event management system<br>
X-WR-CALNAME;VALUE=TEXT:Upcoming library events at Carnation Library<br>
X-WR-CALDESC;VALUE=TEXT:Upcoming library events at Carnation Library<br>
VERSION:2.0<br>
BEGIN:VEVENT<br>
UID:<a href="http://eventinfo.kcls.org/evanced/lib/eventsignup.asp?ID=71954">http://eventinfo.kcls.org/evanced/lib/eventsignup.asp?ID=71954</a><br>
DTSTAMP:20090404T171308Z<br>
DTSTART:20090421T223000Z<br>
DTEND:20090422T003000Z<br>
<strong>TITLE;ENCODING=QUOTED-PRINTABLE:Study Zone</strong><br>
SUMMARY;ENCODING=QUOTED-PRINTABLE:Study Zone<br>
DESCRIPTION;ENCODING=QUOTED-PRINTABLE:Drop-in during scheduled Study Zone hours for free homework help from volunteer tutors. Monday 5:30-7:30pm\nTuesday 3:30-5:30pm\nWednesday, 3:30-5:30pm<br>
LOCATION:Carnation Library at Meeting Room<br>
URL:<a href="http://eventinfo.kcls.org/evanced/lib/eventsignup.asp?ID=71954">http://eventinfo.kcls.org/evanced/lib/eventsignup.asp?ID=71954</a><br>
CATEGORIES:Study Zone (K-12)<br>
END:VEVENT<br>
BEGIN:VEVENT</p>
<p><strong>Doug:</strong> I think this is the same issue with Compatibility Hints in iCal4J. "TITLE" is a non-standard property - to be technically correct it should be "X-TITLE".</p>

                        </div>
                    
                                                        
            <div class="wd-adunit">
<script type="text/javascript"><!--
google_ad_client = "pub-4131765956051719";
/* Wikidot 300x250 free site bottom */
google_ad_slot = "8653165395";
google_ad_width = 300;
google_ad_height = 250;
//-->
</script>
<script type="text/javascript" src="./Wild Examples - iCalendar Validation_files/show_ads.js">
</script><ins style="display:inline-table;border:none;height:250px;margin:0;padding:0;position:relative;visibility:visible;width:300px"><ins id="aswift_1_anchor" style="display:block;border:none;height:250px;margin:0;padding:0;position:relative;visibility:visible;width:300px"><iframe allowtransparency="true" frameborder="0" height="250" hspace="0" marginwidth="0" marginheight="0" onload="var i=this.id,s=window.google_iframe_oncopy,H=s&amp;&amp;s.handlers,h=H&amp;&amp;H[i],w=this.contentWindow,d;try{d=w.document}catch(e){}if(h&amp;&amp;d&amp;&amp;(!d.body||!d.body.firstChild)){if(h.call){setTimeout(h,0)}else if(h.match){w.location.replace(h)}}" scrolling="no" vspace="0" width="300" id="aswift_1" name="aswift_1" style="left:0;position:absolute;top:0;"></iframe></ins></ins>
        </div>
    
                                            
                                            
                        <!-- google_ad_section_end -->
                    
                        <!-- google_ad_section_start(weight=ignore) -->
                    
                        <div id="page-info-break"></div>
                                                  <div id="page-options-container">
                            <div id="page-info">page revision: 52, last edited: <span class="odate time_1260903264 format_%25e%20%25b%20%25Y%2C%20%25H%3A%25M%20%28%25O%20ago%29" style="display: inline;">15 Dec 2009, 19:54 (1089 days ago)</span></div>
            <div id="page-options-bottom" class="page-options-bottom">
            <a href="javascript:;" id="edit-button">Edit</a><a href="javascript:;" id="pagerate-button">Rate (<span id="prw54355">0</span>)</a><a href="javascript:;" id="tags-button">Tags</a>
    <a href="javascript:;" id="history-button">History</a> 
    <a href="javascript:;" id="files-button">Files</a> <a href="javascript:;" id="print-button">Print</a> <a href="javascript:;" id="site-tools-button">Site tools</a><a href="javascript:;" id="more-options-button">+&nbsp;Options</a> 
</div>
<div id="page-options-bottom-2" class="page-options-bottom" style="display:none">
    <a href="javascript:;" id="edit-sections-button">Edit Sections</a>
    <a href="javascript:;" id="edit-append-button">Append</a>
    <a href="javascript:;" id="edit-meta-button">Edit Meta</a>
    <a href="javascript:;" id="watchers-button">Watchers</a> 
    <a href="javascript:;" id="backlinks-button">Backlinks</a> 
    <a href="javascript:;" id="view-source-button">Page Source</a> 
    <a href="javascript:;" id="parent-page-button">Parent</a> 
    <a href="javascript:;" id="page-block-button">Lock Page</a>    
    <a href="javascript:;" id="rename-move-button">Rename</a> 
    <a href="javascript:;" id="delete-button">Delete</a> 
</div>
<div id="page-options-area-bottom">
</div>

                            </div>
                                                                <div id="action-area" style="display: none;"></div>
                </div>
            </div>
            
            
            
            <div id="footer" style="display: block; visibility: visible;">
                                    <div class="options" style="display: block; visibility: visible;">
                        <a href="http://www.wikidot.com/doc" id="wikidot-help-button">Help</a>
                        &nbsp;|
                        <a href="http://www.wikidot.com/legal:terms-of-service" id="wikidot-tos-button">Terms of Service</a>
                        &nbsp;|
                        <a href="http://www.wikidot.com/legal:privacy-policy" id="wikidot-privacy-button">Privacy</a>
                        &nbsp;|
                        <a href="javascript:;" id="bug-report-button" onclick="WIKIDOT.page.listeners.pageBugReport(event)">Report a bug</a>
                        &nbsp;|
                        <a href="javascript:;" id="abuse-report-button" onclick="WIKIDOT.page.listeners.flagPageObjectionable(event)">Flag as objectionable</a>
                    </div>
                    Powered by <a href="http://www.wikidot.com/">Wikidot.com</a> 
                            </div>
                            <div id="license-area" class="license-area">
                                            Unless otherwise stated, the content of this page is licensed under                                         <a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/">Creative Commons Attribution-ShareAlike 3.0 License</a>
                </div>
                        
                            

                        
            
            <div id="extrac-div-1"><span></span></div><div id="extrac-div-2"><span></span></div><div id="extrac-div-3"><span></span></div>
            
                                                    <div id="footer-bar">
  <div>
     </div>
  <h2>Other interesting sites</h2>
  
  <div class="units">
              <div class="unit">
          <div class="inner">
            <a target="_blank" class="image" href="http://boatclub.wikidot.com/">
              <img class="thumbnail" alt="" src="./Wild Examples - iCalendar Validation_files/80.jpg">
            </a>
            <h3><a target="_blank" href="http://boatclub.wikidot.com/">Minnesota Boat Club</a></h3>
            <div class="desc">          
              Member Wiki
            </div>
          </div>
        </div>
              <div class="unit">
          <div class="inner">
            <a target="_blank" class="image" href="http://patriot-box-office.wikidot.com/">
              <img class="thumbnail" alt="" src="./Wild Examples - iCalendar Validation_files/80(1).jpg">
            </a>
            <h3><a target="_blank" href="http://patriot-box-office.wikidot.com/">Patriot Box Office Media Player (PBO)</a></h3>
            <div class="desc">          
              More Than Meets the Eye
            </div>
          </div>
        </div>
              <div class="unit">
          <div class="inner">
            <a target="_blank" class="image" href="http://khaidoan.wikidot.com/">
              <img class="thumbnail" alt="" src="./Wild Examples - iCalendar Validation_files/80(2).jpg">
            </a>
            <h3><a target="_blank" href="http://khaidoan.wikidot.com/">Do only what matters</a></h3>
            <div class="desc">          
              
            </div>
          </div>
        </div>
              <div class="unit">
          <div class="inner">
            <a target="_blank" class="image" href="http://www.trumpetexercises.net/">
              <img class="thumbnail" alt="" src="./Wild Examples - iCalendar Validation_files/80(3).jpg">
            </a>
            <h3><a target="_blank" href="http://www.trumpetexercises.net/">Trumpet exercise database</a></h3>
            <div class="desc">          
              for trumpet players, students and teachers
            </div>
          </div>
        </div>
        </div>
  </div>

                    </div>
        
    </div>
    <!-- These extra divs/spans may be used as catch-alls to add extra imagery. -->
    <div id="extra-div-1"><span></span></div><div id="extra-div-2"><span></span></div><div id="extra-div-3"><span></span></div>
    <div id="extra-div-4"><span></span></div><div id="extra-div-5"><span></span></div><div id="extra-div-6"><span></span></div>
    </div>
    
        
    <div id="page-options-bottom-tips" style="display: none;">
        
    </div>
    <div id="page-options-bottom-2-tips" style="display: none;">
        
        
        
        <div id="discuss-button-hovertip">
            If you want to discuss contents of this page - this is the easiest way to do it.        </div>
        
        
        
        
        
        
                    
            
            
            
            
            </div>
    
    <!-- google_ad_section_end -->
    
    <div id="account-notifications-dummy" style="display: none;"></div>
    
    <div id="dummy-ondomready-block" style="display: none;"></div>
    
        <script type="text/javascript">
    
        (function() {
            var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
            ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
            var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
        })();
    
    </script>
    
        <script type="text/javascript">
    
    _qoptions={
        qacct:"p-edL3gsnUjJzw-"
    };
    (function() {
        var qc = document.createElement('script'); qc.type = 'text/javascript'; qc.async = true;
        qc.src = ('https:' == document.location.protocol ? 'https://secure' : 'http://edge') + '.quantserve.com/quant.js';
        var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(qc, s);
    })();
    
    </script>
    <noscript>
        &lt;img src="http://pixel.quantserve.com/pixel/p-edL3gsnUjJzw-.gif" style="display: none;" border="0" height="1" width="1" alt="Quantcast"/&gt;
    </noscript>
    
    
          

<div id="odialog-hovertips" style="position: absolute; z-index: 100; top: 0px; width: 100%;"><div id="edit-button-hovertip" class="hovertip " style="visibility: visible; opacity: 1; position: absolute; display: none; border: 1px solid black;"><div class="content">
            Click here to edit contents of this page.        </div></div><div id="edit-sections-button-hovertip" class="hovertip " style="visibility: visible; opacity: 1; position: absolute; display: none; border: 1px solid black;"><div class="content">
            Click here to toggle editing of individual sections of the page (if possible).             Watch headings for an "edit" link when available.        </div></div><div id="edit-append-button-hovertip" class="hovertip " style="visibility: visible; opacity: 1; position: absolute; display: none; border: 1px solid black;"><div class="content">
            Append content without editing the whole page source.        </div></div><div id="history-button-hovertip" class="hovertip " style="visibility: visible; opacity: 1; position: absolute; display: none; border: 1px solid black;"><div class="content">
            Check out how this page has evolved in the past.        </div></div><div id="files-button-hovertip" class="hovertip " style="visibility: visible; opacity: 1; position: absolute; display: none; border: 1px solid black;"><div class="content">
            View and manage file attachments for this page.        </div></div><div id="site-tools-button-hovertip" class="hovertip " style="visibility: visible; opacity: 1; position: absolute; display: none; border: 1px solid black;"><div class="content">
            A few useful tools to manage this Site.        </div></div><div id="backlinks-button-hovertip" class="hovertip " style="visibility: visible; opacity: 1; position: absolute; display: none; border: 1px solid black;"><div class="content">
            See pages that link to and include this page.        </div></div><div id="rename-move-button-hovertip" class="hovertip " style="visibility: visible; opacity: 1; position: absolute; display: none; border: 1px solid black;"><div class="content">
            Change the name (also URL address, possibly the category) of the page.        </div></div><div id="view-source-button-hovertip" class="hovertip " style="visibility: visible; opacity: 1; position: absolute; display: none; border: 1px solid black;"><div class="content">
            View wiki source for this page without editing.        </div></div><div id="parent-page-button-hovertip" class="hovertip " style="visibility: visible; opacity: 1; position: absolute; display: none; border: 1px solid black;"><div class="content">  
            View/set parent page (used for creating breadcrumbs and structured layout).        </div></div><div id="abuse-report-button-hovertip" class="hovertip " style="visibility: visible; opacity: 1; position: absolute; display: none; border: 1px solid black;"><div class="content">
                Notify administrators if there is objectionable content in this page.            </div></div><div id="bug-report-button-hovertip" class="hovertip " style="visibility: visible; opacity: 1; position: absolute; display: none; border: 1px solid black;"><div class="content">
                Something does not work as expected? Find out what you can do.            </div></div><div id="wikidot-help-button-hovertip" class="hovertip " style="visibility: visible; opacity: 1; position: absolute; display: none; border: 1px solid black;"><div class="content">
                General Wikidot.com documentation and help section.            </div></div><div id="wikidot-tos-button-hovertip" class="hovertip " style="visibility: visible; opacity: 1; position: absolute; display: none; border: 1px solid black;"><div class="content">
                Wikidot.com Terms of Service - what you can, what you should not etc.            </div></div><div id="wikidot-privacy-button-hovertip" class="hovertip " style="visibility: visible; opacity: 1; position: absolute; display: none; border: 1px solid black;"><div class="content">
                Wikidot.com Privacy Policy.          
            </div></div></div></body></html>